package Server;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.text.Normalizer;
import java.util.ArrayList;

/**
 * 
 * <p>
 * Klasa odpowiadajaca za polaczenie serwera z klientem.
 * Pozwala na wysylanie wiadomosci do klienta.
 * Tworzy nowy watek w ktorym odbierane beda dane od klienta.
 * </p>
 * 
 * @author Dariusz Orlowski
 *
 */
public class ClientService implements Runnable{

    protected Socket clientSocket = null;
    private static ArrayList<ClientService> listaKlientow = new ArrayList<ClientService>();
    
	private InputStream inStream;
	private DataInputStream inDataStream;
	private OutputStream outStream;
	private DataOutputStream outDataStream;

    public ClientService(Socket clientSocket) {
        this.clientSocket = clientSocket;
        
        listaKlientow.add(this);
        
        try {
		      outStream = clientSocket.getOutputStream ();
		      outDataStream = new DataOutputStream ( outStream );
		      inStream = clientSocket.getInputStream ();
		      inDataStream = new DataInputStream ( inStream );
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(this).start();
    }

    //metoda run (watek) odczytujaca wiadomosci wyslane przez klienta
    public void run() {
		byte type;
		int length;
		byte data[];
		try{
			while(true){
				if (inDataStream.available()>=5){//minimum 1 bajt
					type=inDataStream.readByte();
					length=inDataStream.readInt();
					inDataStream.read(data = new byte[length], 0, length);
					//deserializacja + wykonywanie kodu ze wzgledu na typ przesylanej informacji
					if (type==0){//logowanie - odbieranie
						String nick = new String(data);
						Server.server.addPlayer(nick);
					}

				}
				
				
				
				Thread.sleep(10);
	    	}
		}
		catch ( EOFException ex ) {ex.printStackTrace();}
		catch ( IOException ex ) {ex.printStackTrace();}
		catch(InterruptedException ex){ex.printStackTrace();}
   	}    		

    //metoda wysylajaca wiadomosc do klienta
	private void sendToClient(byte type, byte[] data){  
		try{
			outDataStream.write(type);
			outDataStream.writeInt(data.length);
			outDataStream.write(data);
			outDataStream.flush();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
    
	//metoda wysylajaca wiadomosc do wszystkich klientow
	public static void sendToAllClients(byte type, byte[] data){
		for (int i=0;i<listaKlientow.size();i++){
			listaKlientow.get(i).sendToClient(type, data);
		}
	}
	
	//metoda serializujaca obiekt do tablicy bajtow
	private byte[] serializuj(Object o){
		ByteArrayOutputStream baos;
		ObjectOutputStream out;
		
		try
		{
			baos = new ByteArrayOutputStream();
			out = new ObjectOutputStream(baos);	
			out.writeObject(o);
			out.close();
			
			return baos.toByteArray();
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return null;
		}
	}
}